#include "A_Config.h"
#pragma once
typedef struct
{
    uint16_t deviceID_From;
    uint16_t deviceID_To;
    uint8_t payload[232]; // 最大长度： 236 - 4 = 232 byte
} espNowPkt;

typedef void (*ESPNow_Recv_CB)(const uint8_t *pkt, uint8_t size, uint16_t from);
typedef enum
{
    CMD_RESERVE0 = 0,
    CMD_RESERVE1,
    CMD_PING,
    CMD_STOREFILE,
    CMD_LOADFILE,
    CMD_UPDATEWEATHER,
    CMD_SCREENSHOT,
    CMD_PROCIMG,
    CMD_STARTRECORD,
    CMD_RECORD,
    CMD_STOPRECORD,
    CMD_GETIP
} enum_server_cmd_t;

class ESPNowHelper
{
private:
    bool _isStarted = false;
    bool _recvFile(uint32_t timeout);
    bool _sendFile(uint32_t timeout);

public:
    uint16_t myDeviceID = ESPNOW_DEVICEID;
    ESPNow_Recv_CB RecvCB;
    void init();
    void start(uint8_t channel = ESP_NOW_CHANNEL);
    bool isStarted()
    {
        return _isStarted;
    }
    void end();
    void update();
    void reqTimeSync(uint32_t timeout, uint8_t count);
    void sendTo(uint8_t *pkt, uint8_t size, uint16_t deviceID = 0xffff);
    bool sendAndWaitAck(uint8_t *pkt, uint8_t size, uint16_t deviceID, uint32_t timeout = 200, uint32_t retry = 5);

    bool sendFile(File *f, uint16_t deviceID, uint32_t timeout = 1000);
    bool sendFile(uint8_t *buf, size_t size, uint16_t deviceID, uint32_t timeout = 1000);
    bool recvFile(File *f, uint16_t deviceID, uint32_t timeout = 1000);
    bool recvFile(uint8_t *buf, uint16_t deviceID, uint32_t timeout = 1000);
    bool sendCmd(enum_server_cmd_t cmd, const uint8_t *data, uint8_t size, uint16_t deviceID = ESPNOW_MASTER_DEVICEID, bool syncTime = true);
    bool sendCmd(enum_server_cmd_t cmd, const String payload, uint16_t deviceID = ESPNOW_MASTER_DEVICEID, bool syncTime = true)
    {
        return sendCmd(cmd, (const uint8_t *)payload.c_str(), payload.length(), deviceID, syncTime);
    }
    size_t getLastFileSize();
};

extern ESPNowHelper ESPNow;